// 条款20：宁以pass-by-reference-to-const替换pass-by-value
// 核心思想：传递对象给函数时，优先使用常量引用传递而非值传递，以避免不必要的对象拷贝。

// 详细解释：
// 当以值传递方式传递对象时，会调用对象的**拷贝构造函数**创建一个副本
// 对于大型对象或复杂对象，这种拷贝操作可能非常昂贵
// 在继承体系中，值传递还会导致"对象切片"问题(派生类对象被截断为基类对象)

// 不好的方式：值传递
void processWidget(Widget w)
{
    // 函数体
}

// 好的方式：常量引用传递
void processWidget(const Widget &w)
{
    // 函数体
}

// 例外情况：

// 内置类型(int, double等)通常以值传递更高效
// STL迭代器和函数对象通常以值传递
// 小型对象如果拷贝成本低于引用的开销，可以值传递

// 传值不仅会调用拷贝构造函数，还会调用析构函数，如果是浅拷贝还会导致重复析构的问题。
class UnsafeClass
{
private:
    int *data;

public:
    // 构造函数
    UnsafeClass(int value)
    {
        data = new int(value);
    }

    // 默认的拷贝构造函数（浅拷贝）
    // 编译器生成：UnsafeClass(const UnsafeClass& other) { data = other.data; }

    // 析构函数
    ~UnsafeClass()
    {
        delete data; // 释放内存
    }
};

void processObject(UnsafeClass obj)
{
    // 函数结束时，obj被销毁，调用析构函数
    // 此时会释放obj.data指向的内存
}

int main()
{
    UnsafeClass original(42);
    processObject(original); // 传值，调用拷贝构造函数

    // 此时original.data指向的内存已被释放
    // 当original离开作用域时，会再次尝试释放同一块内存，导致崩溃
    return 0;
}